#coding=utf-8
import pygame, os, random
from pygame.locals import * #常用函数和常量
from Prototype import *
from tools.mini_tool import *
from config import *
from tools.monster_AI import update_HostileForces_image

MAIN_DIR = os.path.abspath(os.curdir) #获取当前文件所在的目录绝对路径

FPS = 30 # 帧率
SCREEN_WIDTH, SCREEN_HEIGHT = 1000,650 # 窗口宽、高
BACKGROUND =  'image/maps/desert.png' #背景图

def main():
    # 初始化pygame,为使用硬件做准备
    pygame.init()
    # 创建游戏窗口
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), 0, 32)
    # 设置窗口名称
    pygame.display.set_caption("Demo")
    # 时钟对象，控制运行速率
    fpsClock = pygame.time.Clock()

    map_surface = pygame.image.load(BACKGROUND).convert()  # 加载背景地图
    player1 = MT()  # 创建明特萝莉
    sprite_change_rate = 50 # 移动精灵更换速率 ms/幅

    GJ_effects_list = [] # 攻击特效对象列表
    hostile_forces_list = [] # 敌对势力列表

    while True:
        # 主循环
        screen.blit(map_surface,(-120,-180)) # 绘制背景地图
        passed_time = fpsClock.get_time()  # 上一帧到现在的时间 （毫秒）
        # 检测触发事件
        for event in pygame.event.get():
            if player1.HP <= 0:
                print('die')
                exit()
            if event.type == QUIT:
                exit()
            if event.type == KEYDOWN:
                # 确定移动方向
                if event.key in [K_UP,K_w]:
                    player1.control[UP] = 1
                if event.key in [K_DOWN,K_s]:
                    player1.control[DOWN] = 1
                if event.key in [K_LEFT,K_a]:
                    player1.control[LEFT] = 1
                if event.key in [K_RIGHT,K_d]:
                    player1.control[RIGHT] = 1
                # 攻击
                elif event.key == K_j:
                    player1.control[GJ] = 1
                    gj_effects = player1.create_gj_effects() # 创建攻击特效对象
                    GJ_effects_list.append(gj_effects) # 添加到攻击特效列表
                    gj_effects.move_orientation = player1.face_orientation # 记录攻击特效释放方向
            if event.type == KEYUP:
                # 取消移动状态
                if event.key in [K_UP,K_w]:
                    player1.control[UP] = 0
                if event.key in [K_DOWN,K_s]:
                    player1.control[DOWN] = 0
                if event.key in [K_LEFT,K_a]:
                    player1.control[LEFT] = 0
                if event.key in [K_RIGHT,K_d]:
                    player1.control[RIGHT] = 0
                # 取消攻击状态
                if event.key == K_j:
                    player1.control[GJ] = 0
                    gj_effects.move_status = True # 攻击特效开启移动状态

        # 键盘按下之后的开关值每次循环都加1，用来控制动作顺序
        for action, on_off_value in player1.control.items():
            if on_off_value > 0:  # 去掉此if，可以同时进行多个动作
                player1.control[action] += 1
        action_status = get_action_status(player1.control) #获取行动状态
        # change_print(player1.control)

        # 根据动作状态获取人物显示动作精灵surface，为攻击的话 额外绘制攻击特效精灵surface
        if action_status is not False:
            # 被控制动作
            if action_status in [UP,DOWN,LEFT,RIGHT,LEFT_UP,LEFT_DOWN,RIGHT_UP,RIGHT_DOWN]:
                # 人物移动时
                move_distance = passed_time * (player1.move_rate / 1000)  # 根据时间速率算出应该移动的距离
                player1.move_time += passed_time # 更新移动时间
                player1.move(action_status, move_distance,(SCREEN_WIDTH,SCREEN_HEIGHT)) # 移动角色

                if action_status in [LEFT,RIGHT,LEFT_UP,LEFT_DOWN,RIGHT_UP,RIGHT_DOWN]:
                    player1.face_orientation = action_status  # 左右时改变面向方向
                # 通过 移动时间 除 精灵surface更换速率 再向该动作精灵surface步骤数 取余获得当前action_step_number（动作步骤编号）
                action_step_number = int((player1.move_time//sprite_change_rate)) % len(player1.action_img_resource_dict[player1.face_orientation])
                player1.image = player1.get_action_surface(player1.face_orientation, action_step_number)  # 更新人物显示精灵surface
                player1.adjust_face_orientation() #调整移动方向，移动后不能为45度方向


            elif action_status == GJ:
                # 攻击状态时
                GJ_action_step_number = 0 # 攻击特效编号1
                if player1.control[GJ] > 50:
                    GJ_action_step_number = 1 # 攻击编号2（蓄力变大）
                gj_effects.image = player1.get_action_surface(GJ, GJ_action_step_number) # 更新展示的精灵surface
                gj_effects.draw_sprite(screen) # 绘制攻击特效（释放时）

                # 人物攻击时，暂时以静止状态显示
                action_step_number = 0
                player1.image = player1.get_action_surface(player1.face_orientation,action_step_number)  # 获取人物动作精灵surface
        else:
            # 人物静止时，动作步骤为初始步骤
            action_step_number = 0
            player1.image = player1.get_action_surface(player1.face_orientation,action_step_number)  # 获取人物动作精灵surface

        # 绘制人物显示精灵surface
        player1.draw_sprite(screen)

        player1.width,player1.height = player1.image.get_size() # 更新玩家体型

        # 判断存在的攻击特效对象的移动状态（为Ture，朝当时的人物的面向方向飞出去）, 更新攻击特效体型
        for GJ_effects in GJ_effects_list:
            if GJ_effects.image == None:
                GJ_effects_list.remove(GJ_effects)
                return -1
            try:
                GJ_effects.width,GJ_effects.height = GJ_effects.image.get_size()
            except AttributeError:
                print('按太快，混乱了，居然在删除后才获取尺寸')
            if GJ_effects.move_status is True:
                GJ_move_distance = passed_time * (GJ_effects.GJ_effects_rate / 1000) # 攻击特效应该移动的距离
                if GJ_effects.move_orientation == LEFT:
                    GJ_effects.x -= GJ_move_distance # 现在的设定，只移动x轴
                else:
                    assert GJ_effects.move_orientation == RIGHT,'攻击时人物的面向方向只能是 左 或 右'
                    GJ_effects.x += GJ_move_distance
                GJ_effects.draw_sprite_move(screen) # 根据当前坐标绘制攻击特效精灵surface
            # # 如果与怪物相交，则删除特效，并攻击怪物
            # ret_index = GJ_effects.surface_intersect(hostile_forces_list)
            # if ret_index != -1:
            #     player1.normal_attack(hostile_forces_list[ret_index])
            # 如果移动出屏幕外，从列表中删除攻击对象
            if GJ_effects.x <= 0 or GJ_effects.x >= screen.get_width():
                GJ_effects_list.remove(GJ_effects)

        # # 生成怪物
        if len(hostile_forces_list) < 10:
            hostile_forces_list.append(Tiger(random.randint(1,SCREEN_WIDTH),random.randint(1,SCREEN_HEIGHT)))

        # 循环绘制怪物显示精灵surface,判定状态
        for hostile_forces in hostile_forces_list:
            update_HostileForces_image(hostile_forces,player1,(SCREEN_WIDTH,SCREEN_HEIGHT),passed_time) #更新怪物显示精灵
            hostile_forces.draw_sprite(screen)
            # 如果与玩家相碰,并且自身为攻击状态，则攻击玩家，玩家少一点血，取消攻击状态
            if hostile_forces.surface_intersect([player1])!= -1 and hostile_forces.GJ_status == True:
                hostile_forces.normal_attack(player1) #攻击
                hostile_forces.GJ_status = False
            # # 如果与攻击特效相碰
            # ret_value = hostile_forces.surface_intersect(GJ_effects_list)
            # if ret_value != -1:
            #     player1.normal_attack(hostile_forces) #攻击特效拥有者攻击敌对势力
            # 如果生命值低于等于0，则从存在的敌对势力列表中删除
            # print(hostile_forces.HP,hostile_forces.x,hostile_forces.y)
            if hostile_forces.HP <= 0:
                hostile_forces_list.remove(hostile_forces)

        # 检测碰撞
        # print(player1.HP)
        # 刷新一下画面
        pygame.display.update()
        # 控制一下速率
        fpsClock.tick(FPS)


if __name__ == '__main__':
    main()